/*******************************************************************************
 * Copyright (c) 2011 Grupo de Sistemas Inteligentes (GSI) - DIT UPM
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package es.upm.dit.gsi.eclipse.jadex.adfmanager.wizards;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Button;

/**
 * This page allows to get the following information in order to create the new belief
 *  - fact name
 *  - fact optional attributes: class, description, language and exported
 *  
 *  @author Jorge Valhondo Rama
 */

public class AddBeliefWizardPage2 extends WizardPage {
	private Text nameText;
	private Text classText;
	private Text descriptionText;
	private Text languageText;
	
	private Button addButton;
	private Button deleteButton;
	
	private Table factTable;
	
	
	/**
	 * Constructor for AddBeliefWizardPage2
	 * 
	 * @param pageName
	 */
	public AddBeliefWizardPage2(ISelection selection) {
		super("wizardPage");
		setTitle("Add Belief/set Wizard");
		setDescription("Page 2: fact/s");
	}
	

	/**
	 * @see IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout(4, true);
		container.setLayout(layout);
		layout.horizontalSpacing = 50;
		layout.verticalSpacing = 4;		
		
		Label label1 = new Label(container, SWT.NULL);
		label1.setText("Name: ");
		nameText = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		nameText.setLayoutData(gd);
		nameText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		Label label2 = new Label(container, SWT.NULL);
		label2.setText("Class (optional): ");
		classText = new Text(container, SWT.BORDER | SWT.SINGLE);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		classText.setLayoutData(gd);
		classText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		Label label3 = new Label(container, SWT.NULL);
		label3.setText("Description (optional): ");
		descriptionText = new Text(container, SWT.BORDER | SWT.SINGLE);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		descriptionText.setLayoutData(gd);
		descriptionText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		Label label4 = new Label(container, SWT.NULL);
		label4.setText("Language (optional): ");
		languageText = new Text(container, SWT.BORDER | SWT.SINGLE);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		languageText.setLayoutData(gd);
		languageText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		Label separator1 = new Label(container, SWT.NULL);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		separator1.setLayoutData(gd);
		gd.horizontalSpan = 6;
		
		addButton = new Button(container,SWT.PUSH);
		addButton.setText("Add");
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 1;
		addButton.setLayoutData(gd);
		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if(factTable.getSelection().length > 0){
					addButtonPushed(true);
				}
				else{
					addButtonPushed(false);
				}
			}
		});
		
		Label separator2 = new Label(container, SWT.NULL);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		separator2.setLayoutData(gd);
		gd.horizontalSpan = 2;
		
		deleteButton = new Button(container,SWT.PUSH);
		deleteButton.setText("Delete");
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 1;
		deleteButton.setLayoutData(gd);
		deleteButton.setEnabled(false);
		deleteButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				deleteButtonPushed();
			}
		});
		
		factTable = new Table (container, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
		factTable.setLinesVisible (true);
		factTable.setHeaderVisible (true);
    	gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 4;
    	gd.heightHint = 200;
    	factTable.setLayoutData(gd);
    	String[] titles = {"Name", "Class", "Description", "Language"};
    	for (String s : titles){
    		TableColumn column = new TableColumn (factTable, SWT.NONE);
    		column.setText(s);
    	}	
    	for(TableColumn t : factTable.getColumns()){
    		t.pack();    		
    	}
    	factTable.addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				factSelected();
			}
			
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
    	
		initialize();
		dialogChanged();
		setControl(container);
	}
	
	/**
	 * 
	 * @return an array of facts values
	 */
	public Fact[] getFacts(){
		List<Fact> list = new ArrayList<Fact>();
		for (TableItem item : factTable.getItems()){
			list.add(getFact(item));
		}
		return list.toArray(new Fact[list.size()]);		
	}
	
	/*
	 * This method is called in order to generate a new Fact object
	 * from a table column
	 */
	private Fact getFact(TableItem item){
		String[] content = new String[factTable.getColumnCount()];
		for(int i = 0; i < factTable.getColumnCount(); i++){
			content[i] = item.getText(i);
		}
		if(content.length > 0){
			return new Fact(content);
		}
		return null;
	}

	/*
	 * This method is called when the add button is pushed.
	 * It adds a new fact or modify an existing one depending on 
	 * the desired operation.
	 */
	private void addButtonPushed(Boolean modify){
		if(modify){
			TableItem item = factTable.getSelection()[0];
			item.setText(0,nameText.getText());
			item.setText(1,classText.getText());
			item.setText(2,descriptionText.getText());
			item.setText(3,languageText.getText());
		}
		else{
			Fact f = new Fact(nameText.getText(),
					classText.getText(),
					languageText.getText(),
					descriptionText.getText());
			addFact(f);				
		}
		clearForm();
	}
	
	/*
	 * This method is called when the delete button is pushed
	 */
	private void deleteButtonPushed(){
		factTable.remove(factTable.getSelectionIndices());
		clearForm();
	}
	
	/*
	 * This method is called when a fact is selected in the table
	 */
	private void factSelected(){
		TableItem item = factTable.getSelection()[0];
		nameText.setText(item.getText(0));
		classText.setText(item.getText(1));
		descriptionText.setText(item.getText(2));
		languageText.setText(item.getText(3));		
		deleteButton.setEnabled(true);
		addButton.setText("Modify");
	}
	
	/*
	 * This method is called in order to add a new fact to the table
	 */
	private void addFact(Fact f){
		TableItem item  = new TableItem(factTable, SWT.NONE);
		item.setText(f.getText());
	}
	
	/*
	 * This method clears all the controls text
	 */
	private void clearForm(){
		nameText.setText("");
		classText.setText("");
		descriptionText.setText("");
		languageText.setText("");
		factTable.deselectAll();
		addButton.setText("Add");
		deleteButton.setEnabled(false);
	}

	/*
	 * This method is called when the text of any control changes
	 * or set them to the default selection
	 */
	private void dialogChanged() {
		
		if(factTable.getItems().length == 0){
			updateStatus("At least a fact must be specified");
			return;
		}
		
		for (TableItem item : factTable.getItems()){
			String[] content = new String[factTable.getColumnCount()];
				content[0] = item.getText(0);
				if(content[0].length() == 0){
					updateStatus("At least a name must be specified");
					return;
				}
		}
		
	updateStatus(null);
	}

	/*
	 * This method is called in order to initialize the controls status
	 */
	private void initialize() {
		enabledPropertiesChanged();
	}
	
	/*
	 * This method is called when any 'enable' checkbox is checked
	 */
	private void enabledPropertiesChanged(){
		
	}
	
	/*
	 * This method is called in order to update the status message 
	 */
	private void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}
}

